package com.atguigu.gmall.order.controller;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.cart.client.CartInfoFeignClient;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.user.client.UserInfoFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author 李旭
 * @date 2021/11/30 10:12
 * @Description:
 */
@RestController
@RequestMapping("/api/order")
public class OrderApiController {

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Autowired
    private CartInfoFeignClient cartInfoFeignClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private OrderInfoService orderInfoService;

    //去结算
    @GetMapping("/trade")
    public Map trade(HttpServletRequest request){

        Map  result = new HashMap();
        //1:用户的收货地址集合
        List<UserAddress> userAddressList = userInfoFeignClient.findUserAddressList();
        result.put("userAddressList",userAddressList);
        //2:购物车集合（选中）
        List<CartInfo> cartListAndChecked = cartInfoFeignClient.findCartListAndChecked();
        //2.1:商品清单   (订单详情表）
        List<OrderDetail> orderDetailList = cartListAndChecked.stream().map(cartInfo -> {
            OrderDetail detail = new OrderDetail();
            detail.setImgUrl(cartInfo.getImgUrl());
            detail.setSkuName(cartInfo.getSkuName());
            detail.setSkuId(cartInfo.getSkuId());
            detail.setOrderPrice(cartInfo.getSkuPrice());
            detail.setSkuNum(cartInfo.getSkuNum());
            return detail;
        }).collect(Collectors.toList());
        result.put("detailArrayList",orderDetailList);
        //3：总件数  Stream流 获取总件数的              汇总 ：
        long sum = orderDetailList.stream().
                 collect(Collectors.summarizingInt(OrderDetail::getSkuNum)).getSum();
        result.put("totalNum",sum);
        //4:总金额  BigDecimal
        BigDecimal totalPrice = new BigDecimal(0);
        for (OrderDetail orderDetail : orderDetailList) {
            //totalPrice += orderDetail.getOrderPrice()*orderDetail.getSkuNum()
            totalPrice = totalPrice.add(orderDetail.getOrderPrice().
                    multiply(new BigDecimal(orderDetail.getSkuNum())));
        }
        result.put("totalAmount",totalPrice);
        //5:交易号或订单号或下订号  防止幂等性问题  （防止重复提交订单）
        String tradeNo = UUID.randomUUID().toString();
        //5.1：保存Redis缓存中
        String userId = AuthContextHolder.getUserId(request);
        redisTemplate.opsForValue().set("tradeNo:" + userId,tradeNo);
        //5.2:传递到页面上一份
        result.put("tradeNo",tradeNo);
        return result;
    }

    //提交订单
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo,String tradeNo,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //1:校验交易号、订单号  防止 重复提交订单
        Object no = redisTemplate.opsForValue().get("tradeNo:" + userId);
        if(null == no || !no.equals(tradeNo)){
            //交易号不正确的 不是第一次提交
            return Result.fail().message("不要重复提交订单");
        }
        //1.1.删除Redis缓存中的交易号 以防止重复提交
        redisTemplate.delete("tradeNo:" + userId);
        //2:校验库存 （防止没有货）
        //2.1: 有货： (库存数量-锁定库存) > 购买数量  反之：无货
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            //:true:表示有货  false:表示无货
            boolean isFlag = orderInfoService.checkStock(orderDetail);
            if(!isFlag){
                //无货
                return Result.fail().message(orderDetail.getSkuName() + "[库存不足]");
            }
        }
        //3：保存订单表 订单详情表
        orderInfo.setUserId(Long.parseLong(userId));
        Long orderId = orderInfoService.insertOrder(orderInfo);
        //返回值订单的Id
        return Result.ok(orderId);
    }
    //根据订单的ID 查询订单对象
    @GetMapping("/getOrderInfo/{orderId}")
    public OrderInfo getOrderInfo(@PathVariable Long orderId){

        return orderInfoService.getOrderInfo(orderId);
    }

    //开始拆单
    @PostMapping("/orderSplit")
    public String orderSplit(Long orderId,String wareSkuMap){//仓库编号与商品的对照关系
        //1:开始拆单  一张父订单拆单后 变化N多张子订单
        List<OrderInfo> subOrderInfoList = orderInfoService.orderSplit(orderId,wareSkuMap);
        //2：预计将来返回值
        List<Map> listMap = subOrderInfoList.stream().map(subOrderInfo -> {
            return orderInfoService.initWareData(subOrderInfo);
        }).collect(Collectors.toList());
        return JSONObject.toJSONString(listMap);
    }
}
